package org.yscz.service.impl;

import cn.afterturn.easypoi.cache.manager.IFileLoader;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import org.yscz.common.Constants;
import org.yscz.entity.Testee;
import org.yscz.entity.TesteeGroup;
import org.yscz.entity.vo.TesteeVo;
import org.yscz.mapper.RecordMapper;
import org.yscz.mapper.TesteeGroupMapper;
import org.yscz.mapper.TesteeMapper;
import org.yscz.mqtt.MqttCustomClient;
import org.yscz.service.TesteeService;
import org.yscz.utils.EasyPoiUtil;

import javax.annotation.Resource;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @program: pe
 * @description: 被测人业务层实现类
 * @author: muqs
 * @create: 2021-08-22
 **/
@Service
@Slf4j
public class TesteeServiceImpl extends ServiceImpl<TesteeMapper, Testee> implements TesteeService {

    @Resource
    private TesteeMapper testeeMapper;

    @Resource
    private TesteeGroupMapper testeeGroupMapper;

    @Resource
    private RecordMapper recordMapper;

    @Autowired
    private MqttCustomClient mqttCustomClient;

    /**
     * 人脸库图片地址
     */
    @Value("${yscz.pictures.upload.faceLocation}")
    private String faceLocation;

    @Override
    public TesteeVo add(TesteeVo testeeVo) {
        Testee testee = new Testee();
        BeanUtils.copyProperties(testeeVo, testee);
        testee.setCreateTime(new Date());
        testeeMapper.insert(testee);

        testeeVo.setTesteeId(testee.getTesteeId());
        return testeeVo;
    }

    @Override
    public void modify(TesteeVo testeeVo) {
        Testee testee = new Testee();
        BeanUtils.copyProperties(testeeVo, testee);
        testee.setUpdateTime(new Date());
        testeeMapper.updateById(testee);
    }

    @Override
    public void del(Long testeeId) {
        Testee testee = testeeMapper.selectById(testeeId);
        if (null != testee) {
            //删除人脸库照片
            String httpImageUrl = testee.getImageUrl();
            //f17b6c4a-760a-45bc-bc7d-1a5e02f14182.jpg
            String imageUrl = httpImageUrl.substring(33, httpImageUrl.length());
            //人脸库文件路径
            String fileLocation = faceLocation + File.separator + imageUrl;

            File file = new File(fileLocation);
            if (null != file) {
                file.delete();
            }
        }
        // 删除被测评人
        testeeMapper.deleteById(testeeId);

        //通知算法更新人脸库
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("uuid", "1234");
        mqttCustomClient.publish(Constants.UPDATE_FACE_IMAGE_CONTROL, JSONObject.toJSONString(jsonObject));

        // 删除测评记录
        QueryWrapper recordWrapper = new QueryWrapper();
        recordWrapper.eq("testee_id_fk", testeeId);
        recordMapper.delete(recordWrapper);
    }

    @Override
    public IPage<TesteeVo> listPageByCondition(IPage<TesteeVo> page, Map condition) {
        return testeeMapper.listPageByCondition(page, condition);
    }

    @Override
    public List<TesteeGroup> queryTesteeGroup() {
        QueryWrapper queryWrapper = new QueryWrapper();
        return testeeGroupMapper.selectList(queryWrapper);
    }

    @Override
    public TesteeVo testeeDetail(Long testeeId) {
        return testeeMapper.queryDetail(testeeId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void importExcel(MultipartFile multipartFile) {
        List<TesteeVo> list = null;
        list = EasyPoiUtil.importExcel(multipartFile, 1, 1, TesteeVo.class);
        if (!CollectionUtils.isEmpty(list)) {
            // 查询出班级信息，被测人入库用
            QueryWrapper testeeGroupWrapper = new QueryWrapper();
            List<TesteeGroup> testeeGroups = testeeGroupMapper.selectList(testeeGroupWrapper);
            Map<String, Long> testeeGroupMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(testeeGroups)) {
                testeeGroups.stream().forEach(item -> {
                    if (!testeeGroupMap.containsKey(item.getTesteeGroupName())) {
                        testeeGroupMap.put(item.getTesteeGroupName(), item.getTesteeGroupId());
                    }
                });
            }

//            // 查询出被测人信息,最增量导入
//            QueryWrapper testeeWrapper = new QueryWrapper();
//            List<Testee> testees = testeeMapper.selectList(testeeWrapper);
//            Map<String, Long> testeeMap = new HashMap<>();
//            if (!CollectionUtils.isEmpty(testees)) {
//                testees.stream().forEach(item -> {
//                    testeeMap.put(item.getTesteeName() + "-" + item.getTesteeGroupIdFk(), item.getTesteeId());
//                });
//            }

            // 处理excel表格数据,数据去重
            List<TesteeVo> newTesteeVos = cleanRepeatData(list);
            List<Testee> testeeInserts = new ArrayList<>();
            List<Testee> testeeUpdates = new ArrayList<>();
            newTesteeVos.stream().forEach(item -> {
                Testee testee = new Testee();
                // 如果被测人名字为空,直接跳过
                if (StringUtils.isEmpty(item.getTesteeName())) {
                    return;
                }

                // 获取被测人班级数据
                BeanUtils.copyProperties(item, testee);
                if (!StringUtils.isEmpty(item.getTesteeGroupName())) {
                    if (testeeGroupMap.get(item.getTesteeGroupName()) != null) {
                        testee.setTesteeGroupIdFk(testeeGroupMap.get(item.getTesteeGroupName()));
                    } else {
                        TesteeGroup testeeGroup = new TesteeGroup();
                        testeeGroup.setTesteeGroupName(item.getTesteeGroupName());
                        testeeGroupMapper.insert(testeeGroup);
                        testeeGroupMap.put(testeeGroup.getTesteeGroupName(), testeeGroup.getTesteeGroupId());
                        testee.setTesteeGroupIdFk(testeeGroup.getTesteeGroupId());
                    }
                }

//                if (testeeMap.get(testee.getTesteeName() + "-" + testee.getTesteeGroupIdFk()) != null) {
//                    testee.setTesteeId(testeeMap.get(testee.getTesteeName() + "-" + testee.getTesteeGroupIdFk()));
//                    testee.setUpdateTime(new Date());
//                    testeeUpdates.add(testee);
//                } else {
                testee.setCreateTime(new Date());
                testeeInserts.add(testee);
//                }
            });

            if (!CollectionUtils.isEmpty(testeeInserts)) {
                this.saveBatch(testeeInserts);
            }

            if (!CollectionUtils.isEmpty(testeeUpdates)) {
                this.updateBatchById(testeeUpdates);
            }
        }
    }

    @Override
    public IPage<TesteeVo> manualSelect(IPage<TesteeVo> page, Map condition) {
        return testeeMapper.manualSelect(page, condition);
    }

    private List<TesteeVo> cleanRepeatData(List<TesteeVo> testeeVos) {
        List<TesteeVo> distinctDishList = testeeVos.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(distinctByKeyFunction()))), ArrayList::new));
        return distinctDishList;
    }

    private Function<TesteeVo, String> distinctByKeyFunction() {
        return (TesteeVo testeeVo) -> testeeVo.getTesteeName() + "-" + testeeVo.getTesteeGroupName();
    }
}
